再次回顧 D02 - 程式碼寫作範式的歷史
本來「按照順序給電腦下指令」就能解決的問題漸漸變得越來越難以解決...
昨天我們看到結構化程式設計藉由禁用 goto
解決了程序之間一團亂麻的問題,那接下來還有哪些問題,讓結構化程式設計也應付不來呢 ?
每次我們要改程式,例如新增一個程序(下圖左邊,綠色),如果這個程序會動到資料(下圖右邊,紅色),但剛好這份資料又和其他程序(下圖左邊,黃色)相關.... 一但這種情況出現的多了,在修改時就會很容易又把我們有限的腦子攪成一團亂麻。
為了解決這個問題,物件導向程式設計把緊密相關的程序和資料包在一起,互不影響,這就是封裝(上圖右邊)。
可是把緊密相關的部份封裝起來以後,如果遇到有其他功能要基於原本的功能延伸,難道要複製貼上重新寫一份嗎? 很明顯這又違背了另外一個重要原則
DRY (Don't Repeat Youself)
於是又有了基於以現有封裝好的物件的的基礎下進行擴展的做法出現,這就是繼承
即使有了封裝與繼承,還是撞到 DRY 問題。
想像有一個類別叫「狗」,有子類別叫「吉娃娃」、「博美」、「臘腸」、「柴犬」、「哈士奇」、「杜賓」,每一種狗都會「叫」,但是因為每一種狗叫聲都不一樣,所以我們有好多都是狗叫但叫法不同的「狗叫 function」。
當我們手上有一隻狗,每次想讓他叫的時候都要先具體確認他是哪一種狗,再請他按照對應的叫法發出叫聲實在是有點辛苦 ... 於是透過「狗」這個共通的界面讓去觸發,這就是多型。
說白了其實也就是把選擇實際執行的狗叫的流程封裝進「狗」這個類別。
透過上面的分析,我自己也越發清楚的認識到,物件導向的核心其實就是 封裝。無論是 繼承 或是 多型 主要是在封裝的同時盡量滿足 DRY 原則,也許還有別得方法可以取代,唯有封裝這個概念,無論是在哪種設計方式下都不可或缺。